from fastapi import HTTPException
from passlib.context import CryptContext
import jwt
from datetime import datetime, timedelta
from fastapi.security import OAuth2PasswordRequestForm

from apps.database import engine, SessionLocal
from modules.user import User

# JWT配置
SECRET_KEY = "tianjin666"  # 生产环境应从环境变量获取
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def get_password_hash(password):
    return pwd_context.hash(password)


class UserLogin:

    # 用户注册
    def user_register(self, user_form: dict, db=SessionLocal()):
        try:
            if db.query(User).filter(User.username == user_form["username"]).first():
                raise HTTPException(status_code=400, detail="用户名已被注册")
            # 创建新用户
            password = get_password_hash(user_form["password"])
            new_user = User(username=user_form["username"], password=password)

            db.add(new_user)
            db.commit()
            return {"code": 200, "message": "用户注册成功"}
        except Exception as e:
            return {"code": 500, "message": str(e)}
        finally:
            db.close()

    # 用户登录
    def user_login(self, user_form: dict, db=SessionLocal()):
        try:
            user = db.query(User).filter(User.username == user_form["username"]).first()
            if not user or not pwd_context.verify(user_form["password"], user.password):
                raise HTTPException(
                    status_code=401,
                    detail="用户名或密码错误",
                    headers={"WWW-Authenticate": "Bearer"},
                )

            # 生成JWT
            access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
            access_token = jwt.encode(
                {"sub": user.username, "exp": datetime.utcnow() + access_token_expires},
                SECRET_KEY,
                algorithm=ALGORITHM,
            )

            return {"code": 200, "accessToken": access_token, "token_type": "bearer"}
        except Exception as e:
            return {"code": 500, "message": str(e)}
        finally:
            db.close()
